﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.IO;
using System.ServiceModel.Syndication;
using System.Xml.Serialization;

namespace dasBlog.Storage
{
    [DataContract(Namespace = Names.DataContractNamespace)]
    public sealed class StreamStorageInfo : IEntry<StreamStorageInfo>
    {
        [DataMember(IsRequired = true, EmitDefaultValue = false)]
        public Moniker Id;
        [DataMember(IsRequired = false, EmitDefaultValue = false)]
        public long Size;
        [DataMember(IsRequired = true, EmitDefaultValue = false)]
        public string ContentType;
        [DataMember(IsRequired = true, EmitDefaultValue = false)]
        public DateTime Created;
        [DataMember(EmitDefaultValue = false)]
        public List<string> Categories { get; set; }

        public string CategoriesAsString
        {
            get
            {
                StringBuilder tags = new StringBuilder();
                foreach (string s in Categories)
                {
                    if (tags.Length > 0) tags.Append(';');
                    tags.Append(s);
                }
                return tags.ToString();
            }
            set
            {
                Categories = new List<string>();
                if (value != null)
                {
                    var list = new List<string>(value.Split(';'));
                    foreach (string s in list)
                    {
                        string tag = s.Trim();
                        if (!string.IsNullOrEmpty(tag))
                        {
                            Categories.Add(tag);
                        }
                    }
                }
            }
        }

        public StreamStorageInfo()
        {
        }

        public SyndicationItem ToSyndicationItem<T>()
        {
            var item = new SyndicationItem
            {
                Title = new TextSyndicationContent(Id.ToString()),
            };
            foreach (SyndicationCategory cat in from string s in this.Categories select new SyndicationCategory(s))
            {
                item.Categories.Add(cat);
            }
            item.Links.Add(SyndicationLink.CreateMediaEnclosureLink(this.Id.ToUri(), this.ContentType, this.Size));
            return item;
        }

        public bool IsAuthorized(System.IdentityModel.Claims.ClaimSet claim)
        {
            return true;
        }
       
        public ExtensionDataObject ExtensionData { get;set; }
    }

    [MessageContract(IsWrapped = true, WrapperNamespace = Names.IStreamStorageNodeNamespace)]
    public class StreamStorageGetRequest
    {
        [MessageBodyMember( Namespace = Names.IStreamStorageNodeNamespace)]
        public Moniker itemId;
    }

    [MessageContract(IsWrapped = true, WrapperNamespace = Names.IStreamStorageNodeNamespace)]
    public class StreamStorageGetReply
    {
        [MessageHeader]
        public StreamStorageInfo StreamInfo;
        [MessageBodyMember(Namespace = Names.IStreamStorageNodeNamespace)]
        public Stream Stream;
    }

    [MessageContract]
    public class StreamStorageSetRequest
    {
        [MessageHeader(Name = "ContextId", Namespace = Names.IStreamStorageNodeNamespace)]
        public Moniker moniker;
        [MessageHeader(Name = "Name", Namespace = Names.IStreamStorageNodeNamespace)]
        public string name;
        [MessageHeader(Name = "ContentType", Namespace = Names.IStreamStorageNodeNamespace)]
        public string contentType;
        [MessageHeader(Name = "Categories", Namespace = Names.IStreamStorageNodeNamespace)]
        public string[] categories;

        [MessageBodyMember(Namespace = Names.IStreamStorageNodeNamespace)]
        public Stream Stream;
    }

    [MessageContract(IsWrapped=true,WrapperNamespace=Names.IStreamStorageNodeNamespace)]
    public class StreamStorageSetReply
    {
        [MessageBodyMember(Namespace = Names.IStreamStorageNodeNamespace)]
        public StreamStorageInfo StreamInfo;
    }

    [ServiceContract(Name=Names.IStreamStorageNodeName, Namespace = Names.IStreamStorageNodeNamespace)]
    public interface IStreamStorageNode : IStorageNode
    {
        [OperationContract(IsOneWay=false)]
        StreamStorageGetReply GetStream(StreamStorageGetRequest getRequest);
        [OperationContract(IsOneWay = false)]
        StreamStorageSetReply SetStream(StreamStorageSetRequest addRequest);
    }

    public interface IStreamStorageNodeChannel : IStreamStorageNode, IClientChannel { }

    public interface IStreamStorageProvider : IStorageProvider<StreamStorageInfo>
    {
        [OperationContract(IsOneWay = false)]
        StreamStorageGetReply GetStream(StreamStorageGetRequest getRequest);
        [OperationContract(IsOneWay = false)]
        StreamStorageSetReply SetStream(StreamStorageSetRequest addRequest);
    }

    
}
